package arbre.utils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class Verticale implements Serializable{
	private List<Segment> inter;
	private float a;
	private Verticale s;
	private Verticale p;
	private int id;

	/******************* constructeurs ***********************/

	public Verticale(){

	}

	public Verticale(float abs) {
		super();
		this.inter = new ArrayList<Segment>();
		this.a = abs;
	}

	public Verticale(Point p){
		super();
		this.inter= new ArrayList<Segment>();
		this.a = p.getX();
	}



	/******************* overrided method ***********************/


	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Verticale other = (Verticale) obj;
		if (Float.floatToIntBits(a) != Float.floatToIntBits(other.a))
			return false;
		return true;
	}

	
	

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + Float.floatToIntBits(a);
		return result;
	}




	/******************* methodes ***********************/

	public void showIntersection(){
		System.out.println("-----------------\nVerticale : "+ a);
		for(Segment s : inter){
			System.out.println(s.toString());
		}
	}

	/**
	 * @param v verticale a comparer
	 * @param s segment a comparer
	 * @return vrai si le segment s est a gauche de la verticale v 
	 */
	public boolean gauche(Segment s){
		//in teste les coord de s et de v pour savoir si a est completement a gauche de v
		if(s.getDebut().compareTo(s.getFin())<=0){
			if(s.getDebut().getX()<this.a){
				if(s.getFin().getX() <= this.a){
					return true;
				}
			}
			return false;
		}
		else{
			//fin < debut
			if(s.getFin().getX()<this.a){
				if(s.getDebut().getX() <= this.a){
					return true;
				}
			}
			return false;
		}
	}

	/**
	 * @param v verticale a comparer
	 * @param s segment a comparer
	 * @return vrai si le segment s est a droite de la verticale v 
	 */
	public boolean droite(Segment s){
		//idem a droite
		if(s.getDebut().compareTo(s.getFin())<=0){
			if(s.getDebut().getX()>=this.a){
				if(s.getFin().getX() > this.a){
					return true;
				}
			}
			return false;
		}
		else{
			//fin < debut ,traitement inverse
			if(s.getFin().getX()>=this.a){
				if(s.getDebut().getX() > this.a){
					return true;
				}
			}
			return false;
		}
	}

	/**
	 * @param segments liste de segments de la map
	 * @param verticaleDroite verticale a droite de la verticale courante
	 * 
	 * trouve l'ensemble des egments traversant la zone 
	 * entre la veticale courante et verticale droite
	 * @return 
	 */
	public List<Segment> trouverintersection(List<Segment> segments, Verticale verticaleAutre) {
		
		/*
		 * refaire avec les precedente ou suivante
		 */
		//this <= verticale
		if(this.compareTo(verticaleAutre) <= 0){
			for(Segment s: segments){
				//ok si pas à gauche ni a droite
				if(!this.gauche(s) && !verticaleAutre.droite(s)){
					//il n'est ni tout a gauche ni tout a droite, donc coupe
					//on a vu dans le schema au tableau 
					// trois cas: 
					// 	-	soit full gauche
					//	-	soit full droite
					//	-	soit coupant
					//donc on ajoute
					inter.add(s);
				}
			}
		}
		else{
			//this > verticaleAutre
			for(Segment s: segments){
				//ok si pas à gauche ni a droite
				if(!verticaleAutre.gauche(s) && !this.droite(s)){
					//il n'est ni tout a gauche ni tout a droite, donc coupe
					//on avu dnas le schema au tableua que les cas bizarre sont impossible
					//donc on ajoute
					inter.add(s);
				}
			}
		}
		return getIntersections();

	}
	/********************* Getters and Setters ******************/

	public List<Segment> getIntersections() {
		return inter;
	}

	public void setIntersections(List<Segment> intersections) {
		this.inter = intersections;
	}


	public float getAbs() {
		return a;
	}

	public void setAbs(float abs) {
		this.a = abs;
	}

	@Override
	public String toString() {
		return "<verticale abs=\""+a+"\"/>\n";
	}
	
	public String toDot(){
		return "v"+id;
	}

	public Verticale getSuivante() {
		return s;
	}

	public void setSuivante(Verticale suivante) {
		this.s = suivante;
	}

	public Verticale getPrecedente() {
		return p;
	}

	public void setPrecedente(Verticale precedente) {
		this.p = precedente;
	}

	public int compareTo(Verticale o) {
		if(this.a < o.getAbs()){
			return -1;
		}
		else if(this.a > o.getAbs()){
			return 1;
		}
		return 0;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}



}
